
import os,sys,time,random
import pyautogui
import pyperclip

from io import BytesIO
from PIL import Image
from win32.lib import win32con as con
from win32 import win32clipboard as clb
from win32 import win32gui as gui
from win32 import win32api as api
from win32 import win32process as process
from pynput import keyboard
from wechatdata import data_prase as wdp
from image_position import image_position
import signal
from demo_keyboard import keyboard_listen_init
from pypinyin import pinyin, lazy_pinyin
from pywubi import wubi

search_point5rgb = [(233, 233, 233), (229, 229, 229), (226, 226, 226), (247, 247, 247), (226, 226, 226)]
# input_point5rgb = [(214, 214, 214), (214, 214, 214), (214, 214, 214), (233, 230, 229), (236, 236, 236)]
# input1_point5rgb = [(214, 214, 214), (214, 214, 214), (214, 214, 214), (200, 197, 196), (236, 236, 236)]
input_point6rgb = [(214, 214, 214), (214, 214, 214), (214, 214, 214), (245, 245, 245), (236, 236, 236), (245, 245, 245)]
at_point5rgb = [(213, 213, 215), (235, 235, 235), (237, 237, 237), (237, 237, 237), (213, 213, 215)]

BASE_DIR = os.path.dirname(os.path.abspath(__file__))


def search_by_name(win, name) :
    x, y = win.get_abs_position("search")
    pyautogui.moveTo(x, y)
    pyautogui.click()
    pyperclip.copy(name)
    pyautogui.hotkey('ctrl', 'v')
    time.sleep(0.5)
    pyautogui.press('enter')

def send_message(msg) :
    time.sleep(random.uniform(0.2, 0.5))
    pyperclip.copy(msg)
    time.sleep(random.uniform(0.1, 0.5))
    pyautogui.hotkey('ctrl', 'v')
    pyautogui.press('enter')

def send_msg_list(msglist) :
    for onemsg in msglist:
        send_message(onemsg)

def send_text_message_list(msglist, win=None, name=None) :
    if win != None and name != None:
        search_by_name(win, name)
    send_msg_list(msglist)

def copy_image_to_clip(imagepath) :
    if not os.path.exists(imagepath) :
        return
    image = Image.open(imagepath)
    # 声明output字节对象
    output = BytesIO()
    # 用BMP (Bitmap) 格式存储
    # 这里是位图，然后用output字节对象来存储
    image.save(output, 'BMP')
    # BMP图片有14字节的header，需要额外去除
    data = output.getvalue()[14:]
    # 关闭
    output.close()
    clb.OpenClipboard()
    clb.EmptyClipboard()
    clb.SetClipboardData(clb.CF_DIB, data)
    clb.CloseClipboard()
    time.sleep(1)

def copy_text_to_clip(text) :
    clb.OpenClipboard()
    clb.EmptyClipboard()
    clb.SetClipboardData(clb.CF_UNICODETEXT, text)
    clb.CloseClipboard()
    time.sleep(1)

def send_image_message(imagepath) :
    if not os.path.exists(imagepath) :
        return
    copy_image_to_clip(imagepath)
    time.sleep(random.uniform(0.1, 0.5))
    pyautogui.hotkey('ctrl', 'v')
    time.sleep(random.uniform(0.1, 0.5))
    pyautogui.press('enter')

def send_image_message_list(imagelist, win=None, name=None) :
    if win != None and name != None:
        search_by_name(win, name)
    for oneimg in imagelist:
        send_image_message(oneimg)

def at_one_peopoe(win, name) :
    if len(name) <= 1:
        return False
    pyautogui.hotkey('shift', '2')
    for onechar in name:
        if onechar >= 'a' and onechar <= 'z':
            pyautogui.press(onechar)
    pyautogui.hotkey(' ')
    time.sleep(0.2)

    xs, ys = win.get_abs_position("input")
    _, _, xe, ye = win.get_image_rect()
    atimg = image_position()
    atimg.set_image_data(xs, ys, xe, ye)
    pos = atimg.get_position_by_5point_byx(at_point5rgb)
    if pos == None:
        pyautogui.press('backspace')
        pyautogui.press('backspace')
        pyautogui.press('backspace')
        return False
    offsetpos = (pos[0], pos[1])
    atimg.add_img_position("atone", offsetpos)
    
    x, y = atimg.get_abs_position("atone")
    pyautogui.moveTo(x + 10, y + 20)
    pyautogui.click()
    return True

def send_atone_message_list(atmsg, win, name=None) :
    if win == None:
        print('\t error at people fail!')
        return
    if name != None:
        search_by_name(win, name)
    atlen = 0
    for atone in atmsg:
        onelist = wubi(atone)
        for one in onelist:
            atret = at_one_peopoe(win, one)
            if atret == True:
                atlen = atlen + 1
                break
    if atlen == len(atmsg):
        pyautogui.press('enter')
    else:
        print('\t error at people', atlen, 'less than ', len(atmsg))

def find_pid_by_name(appname):
    allpids = process.EnumProcesses()
    for pid in allpids:
        try:
            handle = api.OpenProcess(con.PROCESS_QUERY_INFORMATION | con.PROCESS_VM_READ, False, pid)
            exepath = process.GetModuleFileNameEx(handle, 0)
            if appname in exepath:
                return pid
        except:
            pass
    return None

def find_windows_by_pid(pid):
    if pid is None:
        return None
    win = gui.FindWindow(None, 'wechat')
    win = gui.FindWindow('WeChatMainWndForPC', '微信')
    print(win)
    print(gui.GetClassName(win))
    if win == None:
        return None
    gui.ShowWindow(win, con.SW_SHOWMINIMIZED)
    gui.ShowWindow(win, con.SW_SHOWNORMAL)
    gui.ShowWindow(win, con.SW_SHOW)
    # gui.SetWindowPos(win, con.HWND_TOP, 0, 0, 500, 700, con.SWP_SHOWWINDOW)
    gui.SetForegroundWindow(win)  # 获取控制
    # time.sleep(1)
    return win

def init_wechat_windows_position():
    pid = find_pid_by_name('WeChat.exe')
    if pid is None:
        return None
    win = find_windows_by_pid(pid)
    if win is None:
        return None
    
    x, y, x1, y1 = gui.GetWindowRect(win)
    print(gui.GetWindowRect(win))
    print('wechat pos :', x, y)
    pimg = image_position()
    pimg.set_image_data(x, y, x1, y1)

    pos = pimg.get_position_by_5point_byx(search_point5rgb)
    if pos == None:
        return None
    offsetpos = (pos[0] + 100, pos[1] + 10)
    pimg.add_img_position("search", offsetpos)
    search_by_name(pimg, '文件传输助手')
    pimg.set_image_data(x, y, x1, y1)

    # pos = pimg.get_position_by_5point_byx(input_point5rgb)
    # if pos == None:
    #     pos = pimg.get_position_by_5point_byx(input1_point5rgb)
    #     if pos == None:
    #         return None
    
    pos = pimg.get_position_by_6point_byx(input_point6rgb)
    if pos == None:
        return None
    offsetpos = (pos[0], pos[1])
    pimg.add_img_position("input", offsetpos)
    offsetpos = (pos[0] + 50, pos[1] + 50)
    pimg.add_img_position("inputedit", offsetpos)
    pimg.print_img_position()
    return pimg

def signal_handle(signum, frame):
    print(os.getpid(), signum, frame)
    sys.exit(0)

def main():
    wechatpos = init_wechat_windows_position()
    if wechatpos == None :
        return None
    
    signal.signal(signal.SIGINT, signal_handle) # ctrl + c
    # signal.signal(signal.SIGTSTP, signal_handle) # ctrl + z
    signal.signal(signal.SIGTERM, signal_handle)
    keyboard_listen_init(os.getpid())

    # return
    configdata = wdp.read_data_from_csv(os.path.join(BASE_DIR, 'wedata.csv'))
    optlen = len(configdata)
    print(optlen)

    # return
    pos = 0
    lastone = None
    for one in configdata:
        pos = pos + 1
        name, (txttype, txt), (imgtype, img), repeat, (attype, atone) = one
        if repeat == 0 and lastone != None:
            (txttype, txt), (imgtype, img), repeat = lastone
        search_by_name(wechatpos, name)
        print(pos, name, 'repeat', repeat)
        if txttype:
            print('\t', txt)
            send_text_message_list(txt)
        if imgtype:
            print('\t', img)
            send_image_message_list(img)
        if attype:
            print('\t', atone)
            send_atone_message_list(atone, wechatpos)
        lastone = ((txttype, txt), (imgtype, img), repeat)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        os._exit(1)

